"""
基础工具函数模块
==============

提供通用的工具函数，不依赖其他内部模块。
"""

import os
import sys
import uuid
import importlib
from pathlib import Path
from typing import Any, Optional, Union, Dict
from datetime import datetime
import logging

logger = logging.getLogger(__name__)


def safe_import(module_name: str, fallback: Any = None) -> Any:
    """
    安全导入模块，失败时返回fallback值
    
    Args:
        module_name: 模块名称
        fallback: 导入失败时的回退值
    
    Returns:
        导入的模块或回退值
    """
    try:
        return importlib.import_module(module_name)
    except ImportError as e:
        logger.debug(f"Failed to import {module_name}: {e}")
        return fallback


def get_project_root() -> Path:
    """
    获取项目根目录路径
    
    Returns:
        项目根目录的Path对象
    """
    # 从当前文件开始，向上查找包含特定文件的目录
    current_path = Path(__file__).parent
    
    # 查找标识文件
    root_indicators = [
        'pyproject.toml',
        'setup.py',
        'requirements.txt',
        '.git',
        'README.md'
    ]
    
    for parent in [current_path] + list(current_path.parents):
        for indicator in root_indicators:
            if (parent / indicator).exists():
                return parent
    
    # 如果找不到，返回当前文件的父目录的父目录（shared的父目录）
    return current_path.parent.parent


def ensure_dir(path: Union[str, Path]) -> Path:
    """
    确保目录存在，如果不存在则创建
    
    Args:
        path: 目录路径
    
    Returns:
        目录的Path对象
    """
    path = Path(path)
    try:
        path.mkdir(parents=True, exist_ok=True)
    except (FileExistsError, OSError) as e:
        logger.debug(f"Directory creation issue for {path}: {e}")
    return path


def format_datetime(dt: Optional[datetime] = None, format_str: str = "%Y-%m-%d %H:%M:%S") -> str:
    """
    格式化日期时间
    
    Args:
        dt: 日期时间对象，默认为当前时间
        format_str: 格式字符串
    
    Returns:
        格式化后的日期时间字符串
    """
    if dt is None:
        dt = datetime.utcnow()
    return dt.strftime(format_str)


def generate_request_id() -> str:
    """
    生成请求ID
    
    Returns:
        UUID格式的请求ID
    """
    return str(uuid.uuid4())


def generate_trace_id() -> str:
    """
    生成追踪ID
    
    Returns:
        UUID格式的追踪ID
    """
    return str(uuid.uuid4())


def is_development() -> bool:
    """
    判断是否为开发环境
    
    Returns:
        是否为开发环境
    """
    env = os.getenv('ENVIRONMENT', 'development').lower()
    return env in ['development', 'dev']


def is_production() -> bool:
    """
    判断是否为生产环境
    
    Returns:
        是否为生产环境
    """
    env = os.getenv('ENVIRONMENT', 'development').lower()
    return env in ['production', 'prod']


def is_testing() -> bool:
    """
    判断是否为测试环境
    
    Returns:
        是否为测试环境
    """
    env = os.getenv('ENVIRONMENT', 'development').lower()
    return env in ['testing', 'test']


def get_env_var(key: str, default: Any = None, required: bool = False) -> Any:
    """
    获取环境变量
    
    Args:
        key: 环境变量名
        default: 默认值
        required: 是否必需
    
    Returns:
        环境变量值
    
    Raises:
        ValueError: 当required=True且环境变量不存在时
    """
    value = os.getenv(key, default)
    
    if required and value is None:
        raise ValueError(f"Required environment variable '{key}' is not set")
    
    return value


def parse_bool(value: Union[str, bool]) -> bool:
    """
    解析布尔值
    
    Args:
        value: 要解析的值
    
    Returns:
        布尔值
    """
    if isinstance(value, bool):
        return value
    
    if isinstance(value, str):
        return value.lower() in ('true', '1', 'yes', 'on')
    
    return bool(value)


def parse_int(value: Union[str, int], default: int = 0) -> int:
    """
    解析整数值
    
    Args:
        value: 要解析的值
        default: 默认值
    
    Returns:
        整数值
    """
    if isinstance(value, int):
        return value
    
    try:
        return int(value)
    except (ValueError, TypeError):
        return default


def parse_float(value: Union[str, float], default: float = 0.0) -> float:
    """
    解析浮点数值
    
    Args:
        value: 要解析的值
        default: 默认值
    
    Returns:
        浮点数值
    """
    if isinstance(value, (int, float)):
        return float(value)
    
    try:
        return float(value)
    except (ValueError, TypeError):
        return default


def deep_merge(dict1: Dict, dict2: Dict) -> Dict:
    """
    深度合并两个字典
    
    Args:
        dict1: 第一个字典
        dict2: 第二个字典
    
    Returns:
        合并后的字典
    """
    result = dict1.copy()
    
    for key, value in dict2.items():
        if key in result and isinstance(result[key], dict) and isinstance(value, dict):
            result[key] = deep_merge(result[key], value)
        else:
            result[key] = value
    
    return result


def sanitize_filename(filename: str) -> str:
    """
    清理文件名，移除不安全字符
    
    Args:
        filename: 原始文件名
    
    Returns:
        清理后的文件名
    """
    import re
    # 移除或替换不安全字符
    sanitized = re.sub(r'[<>:"/\\|?*]', '_', filename)
    # 移除连续的点
    sanitized = re.sub(r'\.{2,}', '.', sanitized)
    # 确保不以点开头或结尾
    sanitized = sanitized.strip('.')
    return sanitized or 'unnamed'


def get_file_size_mb(file_path: Union[str, Path]) -> float:
    """
    获取文件大小（MB）
    
    Args:
        file_path: 文件路径
    
    Returns:
        文件大小（MB）
    """
    try:
        size_bytes = Path(file_path).stat().st_size
        return size_bytes / (1024 * 1024)
    except (OSError, FileNotFoundError):
        return 0.0


def truncate_string(text: str, max_length: int, suffix: str = "...") -> str:
    """
    截断字符串
    
    Args:
        text: 原始文本
        max_length: 最大长度
        suffix: 后缀
    
    Returns:
        截断后的字符串
    """
    if len(text) <= max_length:
        return text
    
    return text[:max_length - len(suffix)] + suffix


def mask_sensitive_data(data: str, mask_char: str = "*", visible_chars: int = 4) -> str:
    """
    遮盖敏感数据
    
    Args:
        data: 敏感数据
        mask_char: 遮盖字符
        visible_chars: 可见字符数
    
    Returns:
        遮盖后的数据
    """
    if len(data) <= visible_chars:
        return mask_char * len(data)
    
    return data[:visible_chars] + mask_char * (len(data) - visible_chars)


# 导出主要函数
__all__ = [
    "safe_import",
    "get_project_root",
    "ensure_dir",
    "format_datetime",
    "generate_request_id",
    "generate_trace_id",
    "is_development",
    "is_production",
    "is_testing",
    "get_env_var",
    "parse_bool",
    "parse_int",
    "parse_float",
    "deep_merge",
    "sanitize_filename",
    "get_file_size_mb",
    "truncate_string",
    "mask_sensitive_data"
]
